package v1

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	"net/http"
	"net/url"
	"reflect"
	"server/internal/model"
	"server/pkg/app"
	"server/pkg/excel"
	"strconv"
)

func CreateFio(c *gin.Context) {
	fio := &model.Fio{}
	ShouldBind(fio, c)
	err := fio.Create()
	if err != nil {
		c.String(http.StatusOK, err.Error())
		return
	}
	c.String(http.StatusOK, "创建fio性能数据成功")
}

func ListFio(c *gin.Context) {
	fio := &model.Fio{}
	pages := &app.Page{}
	pages.Info(c)
	fio_list, total := fio.List(pages)
	c.JSON(http.StatusOK, gin.H{
		"total": total,
		"data":  fio_list,
	})
}

func ExportExcelFio(c *gin.Context) {
	fio := &model.Fio{}
	pages := &app.Page{}
	pages.Page = -1
	fio_list, _ := fio.List(pages)
	l := excel.NewMyExcel()
	l.File.SetSheetName("Sheet1", "data")
	data := []interface{}{}
	for _, fio := range fio_list {
		data = append(data, fio)
	}
	ExportExcelByStruct(l.File, data, "fio", "data", c)
}

// excel导出(数据源为Struct) []interface{}
func ExportExcelByStruct(File *excelize.File, data []interface{}, fileName string, sheetName string, c *gin.Context) error {
	File.SetSheetName("Sheet1", sheetName)
	header := make([]string, 0)
	d := data[0]
	t := reflect.TypeOf(d)
	value := reflect.ValueOf(d)
	for l := 0; l < t.NumField(); l++ {
		val := value.Field(l).Interface()
		v1 := reflect.ValueOf(val)
		if v1.Kind() == reflect.Struct || v1.Kind() == reflect.Slice {
			continue
		}
		header = append(header, value.Type().Field(l).Name)
	}

	rowStyleID, _ := File.NewStyle(
		&excelize.Style{
			Font: &excelize.Font{
				Bold:   true,
				Color:  "#020511",
				Size:   8,
				Family: "微软雅黑"},
			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
			Border: []excelize.Border{
				{Type: "left", Color: "000000", Style: 1},
				{Type: "top", Color: "000000", Style: 1},
				{Type: "right", Color: "000000", Style: 1},
				{Type: "bottom", Color: "000000", Style: 1},
			}})

	_ = File.SetSheetRow(sheetName, "A1", &header)
	_ = File.SetRowHeight(sheetName, 1, 20)

	length := len(header)
	headStyle := excel.Letter(length)

	var lastRow string
	var widthRow string
	for k, v := range headStyle {
		if k == length-1 {
			lastRow = fmt.Sprintf("%s1", v)
			widthRow = v
		}
	}
	if err := File.SetColWidth(sheetName, "A", widthRow, 8); err != nil {
		fmt.Print("错误--", err.Error())
	}
	rowNum := 1
	for _, v := range data {
		t = reflect.TypeOf(v)
		value = reflect.ValueOf(v)
		row := make([]interface{}, 0)
		for l := 0; l < t.NumField(); l++ {
			val := value.Field(l).Interface()
			v1 := reflect.ValueOf(val)
			if v1.Kind() == reflect.Struct || v1.Kind() == reflect.Slice {
				continue
			}
			row = append(row, val)
		}
		rowNum++

		err := File.SetSheetRow(sheetName, "A"+strconv.Itoa(rowNum), &row)
		if err != nil {
			fmt.Println(err.Error())
		}
		err = File.SetCellStyle(sheetName, fmt.Sprintf("A%d", rowNum), fmt.Sprintf("%s", lastRow),
			rowStyleID)
		if err != nil {
			fmt.Println(err.Error())
		}
	}
	rowStyleID1, _ := File.NewStyle(
		&excelize.Style{
			Font: &excelize.Font{
				Bold:   true,
				Color:  "#020511",
				Size:   8,
				Family: "微软雅黑"},
			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
			Fill:      excelize.Fill{Type: "pattern", Color: []string{"#2e8e19"}, Pattern: 1},
			Border: []excelize.Border{
				{Type: "left", Color: "000000", Style: 1},
				{Type: "top", Color: "000000", Style: 1},
				{Type: "right", Color: "000000", Style: 1},
				{Type: "bottom", Color: "000000", Style: 1},
			}})
	err := File.SetCellStyle(sheetName, "A1", fmt.Sprintf("%s", lastRow), rowStyleID1)
	if err != nil {
		fmt.Println(err.Error())
	}
	disposition := fmt.Sprintf("attachment; filename=%s.xlsx", url.QueryEscape(fileName))
	c.Writer.Header().Set("Content-Type", "application/octet-stream")
	c.Writer.Header().Set("Content-Disposition", disposition)
	c.Writer.Header().Set("Content-Transfer-Encoding", "binary")
	c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
	return File.Write(c.Writer)
}

func UpdateFio(c *gin.Context) {
	fio := &model.Fio{}
	ShouldBind(fio, c)
	err := fio.Update()
	if err != nil {
		c.String(http.StatusOK, err.Error())
		return
	}
	c.String(http.StatusOK, "更新fio性能数据成功")
}

func DeleteFio(c *gin.Context) {
	fio := &model.Fio{}
	id := c.Param("id")
	fio.ID, _ = strconv.Atoi(id)
	err := fio.Delete()
	if err != nil {
		c.String(http.StatusOK, err.Error())
		return
	}
	c.String(http.StatusOK, "删除fio性能数据成功")
}
